<?php

/**
 * @name HttpRequest
 * @author Roman Metlinskyi <r.metlinskyi@gmail.com>
 */

class HttpRequest extends Object implements Iterator
{

  // singleton instance
  private static $instance;
  // iterator values
  private $collection;
  private $pathInfo;

  private $url;

  public function __get($name)
  {
    return $this->exists($name, $this->collection)
            ? $this->access($name, $this->collection)
            : parent::__get($name);
  }

  /*
   * region: ISingleton implement
   */

  private function __construct()
  {
    $this->collection = $_REQUEST;
  }

  private function __clone()
  {

  }

  public static function HttpRequest()
  {
    return  (!isset(self::$instance))
          ? (self::$instance = new self())
          : self::$instance;
  }

  /*
   * region: Properties [GET]
   */

  public function getUrl()
  {
    if(!isset($this->url))
      $this->url = new Uri($this->RequestUrl);

    return $this->url;
  }


  public function getCookies($name = null)
  {
    return $this->access($name, $_COOKIE);
  }

  public function getForm($name = null)
  {
    return $this->access($name, $_POST);
  }

  public function getFiles($name = null)
  {
    return $this->access($name, $_FILES);
  }

  public function getParams($name = null)
  {
    return $this->access($name, $_REQUEST);
  }

  public function getHttpMethod()
  {
    return $_SERVER['REQUEST_METHOD'];
  }

  public function getRequestUrl()
  {
    return $_SERVER['REQUEST_URI'];
  }


  public function getPathInfo()
  {
    if(!isset($this->pathInfo))
      $this->pathInfo = str_replace('index.php','',$_SERVER['PHP_SELF']);

    return $this->pathInfo;
  }

  /*
   * region: Properties [SET]
   */

  private function access($name, $collection)
  {
    $this->collection = $collection;

    if ($name == null)
      return $this;

    if(!$this->exists($name, $this->collection))
      return null;

    $value = $this->collection[$name];
    if(is_array($value)){
      $this->collection = $value;
      return $this;
    }

    return $value;
  }

  private function exists($name, $collection = null)
  {
    if($collection == null)
      $collection = $this->collection;

    return array_key_exists($name, $collection);
  }

  /*
   * region: Iterator implement
   */

  function rewind()
  {
    if(empty($this->collection))
      return null;

    return reset($this->collection);
  }

  function current()
  {
    return current($this->collection);
  }

  function key()
  {
    return key($this->collection);
  }

  function next()
  {
    return next($this->collection);
  }

  function valid()
  {
    if(empty($this->collection))
      return null;

    return key($this->collection) !== null;
  }

  /*
   * return current collection as array
   */
  public function ToArray()
  {
    return (array)$this->collection;
  }

  /*
   * Create object by POST
   */
  public function ToObject($type = null)
  {
    if($type == null)
      return (object) $this->collection;

    if(class_exists($type)){
      $model = new $type();
      foreach ($this->Form($type) as $name => $value){
        if(property_exists($type, $name))
          $model->$name = $value;
      }
      return $model;
    }
    return null;
  }
}